/**
 ****************************************************************
 * @file rfid.c
 *
 * @brief  关于各项指令测试的主要接口
 *
 * @author 
 *
 * 
 ****************************************************************
 */

/*
 * INCLUDE FILES
 ****************************************************************
 */	
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "timer.h"
#include "nfc663.h"
#include "iso14443a.h" 
#include "iso14443b.h" 
#include "felica.h"
#include "iso15693.h"
#include "mifare.h" 
#include "iso14443_4.h"
#include "rfid.h"

tag_info XDATA g_tag_info;

u8 XDATA iso15693_uid[8];


statistics_t XDATA g_statistics;
bool XDATA g_statistic_refreshed;

u32 XDATA g_cos_loop_times = 0;
//bit g_cos_loop = FALSE;
u8 XDATA g_loop_buf[40];//不支持太大的cos指令测试

void com_halt_a(void);
void com_mf1_read(u8 *pcmd);
void com_mf1_write(u8 *pcmd);
void com_mf0_read(u8 *pcmd);
void com_mf0_write(u8 *pcmd);
void com_halt_b(u8 *pcmd);
void com_get_idcard_num(void);
void com_exchange(u8 * pcmd);
void com_multi_exchange_test(u8 *pcmd);
void com_typea_rats(u8 * pcmd);
void com_stay_quiet(u8 *pcmd);
void com_reset_to_ready(u8 *pcmd);
void com_select(u8 *pcmd);
void com_get_block_status(u8 *pcmd);
void com_read_single_block(u8 *pcmd);
void com_write_single_block(u8 *pcmd);
void com_get_sys_info(u8 *pcmd);
void com_lock_block(u8 *pcmd);
void com_read_multiple_block(u8 *pcmd);
void com_write_multiple_block(u8 *pcmd);
void com_write_afi(u8 * pcmd);
void com_lock_afi(u8 *pcmd);
void com_write_dsfid(u8 * pcmd);
void com_lock_dsfid(u8 *pcmd);
void com_mf1_value_block(u8 *pcmd);


u8 com_status_check(char status)
{
	switch(status)
	{
		case MI_NOTAGERR:
			return 0x01;
			
		case MI_INTEGRITY_ERR:
			return 0x02;
			
		case MI_COLLERR:
			return 0x04;
			
		case PROTOCOL_ERR:
			return 0x08;
			
		case MI_COM_ERR:
			return 0x10;
			
		default:
			return 0xFF;
			
	}
}


void rfid_init()
{
	memset(&g_tag_info, 0, sizeof(g_tag_info));
	memset(&g_statistics, 0, sizeof(g_statistics));
}
void rfid_operation(u8 *pcmd)
{
	switch(pcmd[0])
	{
		case COM_PKT_CMD_INIT_TYPEA:
			pcd_config('A');							break;
		case COM_PKT_CMD_INIT_TYPEB:
			pcd_config('B');							break;
		//Type A
		case COM_PKT_CMD_REQA:
			pcd_set_rate('1', 'A');
			com_reqa(pcmd);								break;		
		case COM_PKT_CMD_TYPEA_HALT:
			com_halt_a();								break;
		case COM_PKT_CMD_TYPEA_MF1_READ:
			com_mf1_read(pcmd);							break;
		case COM_PKT_CMD_TYPEA_MF1_WRITE:
			com_mf1_write(pcmd);						break;
		case COM_PKT_CMD_TYPEA_MF1_VALUE_BLOCK_OP:
			com_mf1_value_block(pcmd);
			break;
		case COM_PKT_CMD_TYPEA_MF0_READ:
			com_mf0_read(pcmd);							break;
			break;
		case COM_PKT_CMD_TYPEA_MF0_WRITE:
			com_mf0_write(pcmd);						break;
		case COM_PKT_CMD_TYPEA_RATS:
			com_typea_rats(pcmd);						break;
		//Type B
		case COM_PKT_CMD_REQB:
			pcd_set_rate('1', 'B');
			com_reqb(pcmd);								break;
		case COM_PKT_CMD_TYPEB_HALT:
			com_halt_b(pcmd);							break;
		case COM_PKT_CMD_TYPEB_UID:
			com_get_idcard_num();						break;
		case COM_PKT_CMD_EXCHANGE:
			com_exchange(pcmd);							break;
		case COM_PKT_CMD_MULTI_EXCHANGE_TEST:
			com_multi_exchange_test(pcmd);				break;	
		case COM_PKT_CMD_DESELECT:
			iso14443_4_deselect(0);						break;
		case COM_PKT_CMD_STATISTICS:
			memset(&g_statistics, 0, sizeof(g_statistics));							break;
		//Type F
		case COM_PKT_CMD_FELICA_CONFIG:
			pcd_config('F');														break;
		case COM_PKT_CMD_TYPEC_FELICA_REQC:
			if(pcmd[1] == 0x01)
			{
				printf("212k\n");
				pcd_set_rate('2', 'F');
			}
			else if(pcmd[1] == 0x02)
			{
				printf("424k\n");
				pcd_set_rate('4', 'F');	
			}
			com_reqc(pcmd);															break;
		//Type V
		case COM_PKT_CMD_ISO15693_CONFIG:
			pcd_config('V');															break;
		case COM_PKT_CMD_ISO15693_INVENTORY:
			com_inventory(pcmd);													break;
		case COM_PKT_CMD_ISO15693_STAY_QUIET:
			com_stay_quiet(pcmd);													break;
		case COM_PKT_CMD_ISO15693_RESET_TO_READY:
			com_reset_to_ready(pcmd);												break;
		case COM_PKT_CMD_ISO15693_SELECT:
			com_select(pcmd);														break;
		case COM_PKT_CMD_ISO15693_GET_STATUS:
			com_get_block_status(pcmd);												break;
		case COM_PKT_CMD_ISO15693_GET_SYSTEM:
			com_get_sys_info(pcmd);													break;
		case COM_PKT_CMD_ISO15693_READ_SINGLE:
			com_read_single_block(pcmd);											break;
		case COM_PKT_CMD_ISO15693_WRITE_SINGLE:
			com_write_single_block(pcmd);											break;
		case COM_PKT_CMD_ISO15693_LOCK_BLOCK:
			com_lock_block(pcmd);													break;
		case COM_PKT_CMD_ISO15693_READ_MULTIPLE:
			com_read_multiple_block(pcmd);											break;
		case COM_PKT_CMD_ISO15693_WRITE_MULTIPLE:
			com_write_multiple_block(pcmd);											break;
		case COM_PKT_CMD_ISO15693_WRITE_AFI:
			com_write_afi(pcmd);													break;
		case COM_PKT_CMD_ISO15693_LOCK_AFI:
			com_lock_afi(pcmd);													    break;
		case COM_PKT_CMD_ISO15693_WRITE_DSFID:
			com_write_dsfid(pcmd);													break;
		case COM_PKT_CMD_ISO15693_LOCK_DSFID:
			com_lock_dsfid(pcmd);													break;

		default:
			break;
	}

}

char com_reqa(u8 *pcmd)
{
	char status;
	u8 sak;
	u8 err;
	u8 XDATA buf[10];
	
	g_statistics.reqa_cnt++;
	g_statistic_refreshed=TRUE;

	pcd_default_info();

	status = pcd_request(pcmd[1], g_tag_info.tag_type_bytes);
	//一次防冲突及选卡
	if (status == MI_OK)
	{
		g_tag_info.uid_length = UID_4;
		make_packet(COM_PKT_CMD_CARD_TYPE, g_tag_info.tag_type_bytes, sizeof(g_tag_info.tag_type_bytes));
		
		status = pcd_cascaded_anticoll(PICC_ANTICOLL1, 0, &g_tag_info.serial_num[0]);
		if (status == MI_OK)
		{
			status = pcd_cascaded_select(PICC_ANTICOLL1, &g_tag_info.serial_num[0], &sak);
		}
	}
	//二次防冲突及选卡
	if(status == MI_OK && (sak & BIT2))
	{
		g_tag_info.uid_length = UID_7;
		status = pcd_cascaded_anticoll(PICC_ANTICOLL2, 0, &g_tag_info.serial_num[4]);
		if(status == MI_OK)
		{
			status = pcd_cascaded_select(PICC_ANTICOLL2, &g_tag_info.serial_num[4], &sak);
		}
	}
	//三次防冲突及选卡
	if(status == MI_OK && (sak & BIT2))
	{
		g_tag_info.uid_length = UID_10;
		status = pcd_cascaded_anticoll(PICC_ANTICOLL3, 0, &g_tag_info.serial_num[7]);
		if(status == MI_OK)
		{
			status = pcd_cascaded_select(PICC_ANTICOLL3, &g_tag_info.serial_num[7], &sak);
		}
	}
	//回复uid
	if (status == MI_OK)
	{
		buf[0] = g_tag_info.uid_length;
		memcpy(buf+1, (g_tag_info.uid_length == UID_4 ? &g_tag_info.serial_num[0]:&g_tag_info.serial_num[1]), g_tag_info.uid_length);
		make_packet(COM_PKT_CMD_REQA, buf, g_tag_info.uid_length + 1);
	}

	if(status != MI_OK)
	{
		err = com_status_check(status);
		make_packet(COM_PKT_CMD_ERR_STA_STATISTICS, (u8*)&(err), sizeof(err));
		
		g_statistics.reqa_fail++;
		#if(NFC_DEBUG)
		printf("reqa_fail\n");
		#endif
	}
	return status;
}

void com_halt_a()
{
	u8 status;
	
	status = pcd_hlta();
	make_packet(COM_PKT_CMD_TYPEA_HALT, &status, sizeof(status));
}

void com_mf1_read(u8 *pcmd)
{	
	u8 status;
	u8 block;
	u8 is_a;
	u8 XDATA buf[17];
	
	block = pcmd[1];
	is_a = pcmd[2];

	if(g_tag_info.uid_length == UID_4)
	{
		status = pcd_auth_state((is_a == TRUE ? PICC_AUTHENT1A : PICC_AUTHENT1B), block, &g_tag_info.serial_num[0], &pcmd[3]);		
	}
	else if(g_tag_info.uid_length == UID_7)
	{
		status = pcd_auth_state((is_a == TRUE ? PICC_AUTHENT1A : PICC_AUTHENT1B), block, &g_tag_info.serial_num[4], &pcmd[3]);
	}
	else if(g_tag_info.uid_length == UID_10)
	{
		status = pcd_auth_state((is_a == TRUE ? PICC_AUTHENT1A : PICC_AUTHENT1B), block, &g_tag_info.serial_num[7], &pcmd[3]);	
	}
	
	if (status == MI_OK)
	{
		status = pcd_read(block, buf + 1);
	}
	if (status == MI_OK)
	{
		buf[0] = block;
		make_packet(COM_PKT_CMD_TYPEA_MF1_READ, buf, sizeof(buf));
	}
}

void com_mf1_write(u8 *pcmd)
{
	u8 status;
	u8 block;
	u8 is_a;
	
	block = pcmd[1];
	is_a = pcmd[2];

	if(g_tag_info.uid_length == UID_4)
	{
		status = pcd_auth_state((is_a == TRUE ? PICC_AUTHENT1A : PICC_AUTHENT1B), block, &g_tag_info.serial_num[0], &pcmd[3]);		
	}
	else if(g_tag_info.uid_length == UID_7)
	{
		status = pcd_auth_state((is_a == TRUE ? PICC_AUTHENT1A : PICC_AUTHENT1B), block, &g_tag_info.serial_num[4], &pcmd[3]);
	}
	else if(g_tag_info.uid_length == UID_10)
	{
		status = pcd_auth_state((is_a == TRUE ? PICC_AUTHENT1A : PICC_AUTHENT1B), block, &g_tag_info.serial_num[7], &pcmd[3]);	
	}
	
	if (status == MI_OK)
	{
		status = pcd_write(block, &pcmd[9]);
	}
	make_packet(COM_PKT_CMD_TYPEA_MF1_WRITE, &status, sizeof(status));
}

void com_mf1_value_block(u8 *pcmd)
{
	u8 status;
	u8 block;
	u8 is_a;
	
	block = pcmd[1];
	is_a = pcmd[2];

	if(g_tag_info.uid_length == UID_4)
	{
		status = pcd_auth_state((is_a == TRUE ? PICC_AUTHENT1A : PICC_AUTHENT1B), block, &g_tag_info.serial_num[0], &pcmd[3]);		
	}
	else if(g_tag_info.uid_length == UID_7)
	{
		status = pcd_auth_state((is_a == TRUE ? PICC_AUTHENT1A : PICC_AUTHENT1B), block, &g_tag_info.serial_num[4], &pcmd[3]);
	}
	else if(g_tag_info.uid_length == UID_10)
	{
		status = pcd_auth_state((is_a == TRUE ? PICC_AUTHENT1A : PICC_AUTHENT1B), block, &g_tag_info.serial_num[7], &pcmd[3]);	
	}
	
	if (status == MI_OK)
	{
		status = pcd_valueblock_operation(pcmd[13], block, &pcmd[9]);
	}

}

void com_mf0_read(u8 *pcmd)
{
	u8 status;
	u8 block;
	u8 XDATA buf[17];
	
	block = pcmd[1];
	
	status = pcd_read(block, buf + 1);

	if (status == MI_OK)
	{
		buf[0] = block;
		make_packet(COM_PKT_CMD_TYPEA_MF0_READ, buf, sizeof(buf));
	}
}

void com_mf0_write(u8 *pcmd)
{
	u8 status;
	u8 block;
	
	block = pcmd[1];

	status = pcd_write_ultralight(block, &pcmd[2]);
	
	make_packet(COM_PKT_CMD_TYPEA_MF0_WRITE, &status, sizeof(status));
}

char com_reqb(u8 *pcmd)
{
	int XDATA status;
	u8 XDATA err;
	u8 XDATA i;
	u8 XDATA cnt;
	u8 XDATA ATQB[16];
	u8 XDATA req_code;

	g_statistics.reqb_cnt++;
	g_statistic_refreshed=TRUE;

	pcd_default_info();
	 
	req_code = pcmd[1];
	
	cnt = 3;//应用中 可以使用轮询N次	
	while(cnt--)
	{
		status = pcd_request_b(req_code, 0, 0, ATQB);
		
		if(status == MI_COLLERR)	// 有冲突，超过一张卡
		{
			if((status = pcd_request_b(req_code, 0, 2, ATQB)) != MI_OK)
			{
			   	for (i = 1; i < 4; i++)
			   	{
			    	if((status = pcd_slot_marker(i, ATQB)) == MI_OK) 
					{
						break;
			    	}
			  	}
				if (status == MI_OK)
				{
					break;
				}
			}
			else
			{
				break;
			}
		}
		else if (status == MI_OK)
		{
			break;
		}
	}

	if (status == MI_OK)
	{
		if((pcmd[2] != 0) && (pcmd[2] <= 8))
		{
			pcd_pps_rate_b(PICC_CID, ATQB, pcmd[2]);	
		}
		else
		{
			//typeB 106默认速率
			status = pcd_attri_b(&ATQB[1], 0, ATQB[10]&0x0f, PICC_CID, ATQB);
		}

		if (status == MI_OK)
		{						
			ATQB[0] = 0x50;//恢复默认值
			make_packet(COM_PKT_CMD_REQB, ATQB, 12);
		}
	}
	
	if(status == MI_OK)
	{
	}
	else
	{
		err = com_status_check(status);
		make_packet(COM_PKT_CMD_ERR_STA_STATISTICS, (u8*)&(err), sizeof(err));

		g_statistics.reqb_fail++;
		#if(NFC_DEBUG)
		printf("reqb_fail\n");
		#endif
	}
	
	return status;
}

void com_halt_b(u8 *pcmd)
{
	u8 XDATA status;
	pcmd = pcmd;

	status = iso14443_4_deselect(PICC_CID); //deselect all card
	//status = pcd_halt_b(pcmd + 1);// 4 bytes uid
	
	make_packet(COM_PKT_CMD_TYPEB_HALT, &status, sizeof(status));
}
void com_get_idcard_num()
{
	u8 XDATA id[10];
	char XDATA status;
	
	status = get_idcard_num(id);
	if (status == MI_OK)
	{
		make_packet(COM_PKT_CMD_TYPEB_UID, id, 10);
	}
}

void statistic_print()
{
	if (g_statistic_refreshed == TRUE)
	{
		make_packet(COM_PKT_CMD_STATISTICS, (u8*)&g_statistics, sizeof(g_statistics));
		g_statistic_refreshed = FALSE;
	}
}
void com_typea_rats(u8 * pcmd)
{
	char status;
	u8 CID = 0;
	u8 ats[3];
	u8 rate;   
	transceive_buffer *pi;
	

	pi = &mf_com_data;
	
	status = pcd_rats_a(CID, ats);
	if(status == MI_OK)
	{		
		if (pcmd[1] != 0)
		{//需要做pps指令
			rate = pcmd[1];
			status = pcd_pps_rate(pi, ats, CID, rate);
		}
	}

	if (status != MI_OK)
	{
		g_statistics.atqa_fail++;
	}
	g_statistic_refreshed = TRUE;
	
}
void com_exchange(u8 * pcmd)
{			
	u8 XDATA loop_buf[256];
	char status;
	
	u16 XDATA tx_len;
	unsigned int XDATA rx_len;
	
	g_statistics.cos_cnt++;

	tx_len = pcmd[1];
	memcpy(loop_buf, pcmd + 2, tx_len);
	status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, loop_buf, tx_len, loop_buf, &rx_len);
	if (status == MI_OK && rx_len < sizeof(loop_buf))
	{
		memmove(loop_buf+1, loop_buf, rx_len);
		loop_buf[0]=rx_len;
		make_packet(COM_PKT_CMD_EXCHANGE, (u8*)&loop_buf, rx_len + 1);		
	}
	if (status != MI_OK)
	{
		g_statistics.cos_fail++;
	}
	g_statistic_refreshed = TRUE;
}



void com_multi_exchange_test(u8 *pcmd)
{
//	g_cos_loop = TRUE;
	if(pcmd[1 + sizeof(u32)] + 1 <= sizeof(g_loop_buf))
	{
		g_cos_loop_times = *(u32*)&pcmd[1];
		g_loop_buf[0]= pcmd[sizeof(u32)];
		memcpy(g_loop_buf + 1, pcmd + 1 + sizeof(u32), pcmd[1 + sizeof(u32)] + 1);
	}
	else
	{
		printf("multi cos data > g_loop_buf\n");
	}
}
int com_reqc(u8 *pcmd)
{
	int XDATA status;
	u8 XDATA err;
	u8 XDATA rsp[18];
	u8 XDATA node_code_list[2] = {0x00, 0x00};
	u8 XDATA node_key_version_list[2];
	u8 XDATA node_size;
	u8 XDATA mode;
	u8 XDATA i = 0;
	u8 XDATA service_code_list[2] = {0x0B, 0x10};
	u8 XDATA block_list[2] = {0x80, 0x00};
	u8 XDATA block_size;
	u8 XDATA block_data[16];
	u8 XDATA status_flag[2];
	u8 XDATA write_data[16] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00};
	u8 XDATA syscode_size;
	u8 XDATA syscode_list[2];

	g_statistics.felica_cnt++;	
	g_statistic_refreshed = TRUE;
	
	status = pcd_request_c(&pcmd[4], pcmd[6], pcmd[7], pcmd[1], rsp);

	if(status != MI_OK)
	{
		err = com_status_check(status);
		make_packet(COM_PKT_CMD_ERR_STA_STATISTICS, (u8*)&(err), sizeof(err));
		
		g_statistics.felica_fail++;
		#if(NFC_DEBUG)
		printf("reqc_fail:%d\n", (u16)status);
		#endif

	}
	else 
	{
		make_packet(COM_PKT_CMD_CARD_TYPE, rsp, 18);
		status = pcd_req_resp(&rsp[2], &mode);		//felica请求响应

		if(status == MI_OK)
		{
			#if(NFC_DEBUG)		
//			printf("mode = %d\n", (u16)mode);
			#endif
			status = pcd_req_service(&rsp[2], 1, node_code_list, &node_size, node_key_version_list);		//felica请求服务
			
			if(status == MI_OK)
			{
				#if(NFC_DEBUG)
//				printf("node_size: %d\n", (u16)node_size);
				#endif

				pcd_read_without_encryption(&rsp[2], 1, service_code_list, 1, block_list, sizeof(block_list), &block_size, block_data, status_flag);
				if(status == MI_OK)
				{
					#if(NFC_DEBUG)
//					printf("status_flag: %02x", (u16)status_flag[0]);
//					printf(" %02x\n", (u16)status_flag[1]);
					#endif	

					pcd_write_without_encryption(&rsp[2], 1, service_code_list, 1, block_list, sizeof(block_list), write_data, status_flag);
					if(status == MI_OK)
					{
						#if(NFC_DEBUG)
//						printf("status_flag: %02x", (u16)status_flag[0]);
//						printf(" %02x\n", (u16)status_flag[1]);
						#endif
						
						pcd_req_syscode(&rsp[2], &syscode_size, syscode_list);
						if(status == MI_OK)
						{
							#if(NFC_DEBUG)
//							printf("sys code: %02x", (u16)syscode_list[0]);
//							printf(" %02x\n", (u16)syscode_list[1]);
							#endif
						}
					}

					
				}
			}
		}
	}
	return status;	
}

int com_inventory(u8 *pcmd)
{
	int status;

	u8 XDATA maskval[8];
	u8 XDATA masklen = 0;
	u8 XDATA dsfid;
	u8 XDATA err;
	u8 XDATA i;	
	u8 card_num = 0;

	if(pcmd[4] == TRUE)		//TRUE为轮询射频场内所有标签
	{
		do{		
			status = pcd_inventory(pcmd[1], pcmd[3], maskval, masklen, &dsfid, iso15693_uid);
		
			if(status != MI_OK)
			{

			}
			else
			{
			#if(NFC_DEBUG)
				printf("ISO15693--UID:");
				for(i = 0; i < 7; i ++)
				{
					printf("%02X ", (u16)iso15693_uid[i]);
				}
				printf("%02X\n", (u16)iso15693_uid[i]);
			#endif
				status = pcd_stay_quiet(iso15693_uid, 0x22);
				card_num++;
			}

		}while(status == MI_OK);
		printf("card num = %02d\n\n", (u16)card_num);
	}
	else
	{
		g_statistics.inv_cnt++;
		g_statistic_refreshed = TRUE;
	
		status = pcd_inventory(pcmd[1], pcmd[3], maskval, masklen, &dsfid, iso15693_uid);
	
		if(status != MI_OK)
		{
			err = com_status_check(status);
			make_packet(COM_PKT_CMD_ERR_STA_STATISTICS, (u8*)&(err), sizeof(err));
			
			g_statistics.inv_fail++;
		#if(NFC_DEBUG)
			printf("reqv_fail:%d\n", (u16)status);
		#endif
		}
		else
		{
			make_packet(COM_PKT_CMD_ISO15693_INVENTORY, iso15693_uid, ISO15693_UID_LENGTH);
	
		#if(NFC_DEBUG)
			printf("ISO15693--UID:");
			for(i = 0; i < 7; i ++)
			{
				printf("%02X ", (u16)iso15693_uid[i]);
			}
			printf("%02X\n", (u16)iso15693_uid[i]);
		#endif
		}
	}


	return status;		
}

void com_stay_quiet(u8 *pcmd)
{
	pcd_stay_quiet(iso15693_uid, pcmd[1]);
}

void com_reset_to_ready(u8 *pcmd)
{
	pcd_reset_to_ready(iso15693_uid, pcmd[1]);
}

void com_select(u8 *pcmd)
{
	u8 err = 0;

	pcd_select(iso15693_uid, pcmd[1], &err);
	if(err != 0)
	{
	#if(NFC_DEBUG)
		printf("ErrCode = %02x\n", (u16)err);
	#endif
	}
}
void com_get_sys_info(u8 *pcmd)
{
	u8 err = 0;
	u8 resbuff[15];
	u16 bufflen;
	int status = MI_OK;
	
	status = pcd_get_system_information(iso15693_uid, pcmd[1], &err, resbuff, &bufflen);
	
	if(status == MI_OK)
	{
		if(err != 0)
		{
		#if(NFC_DEBUG)
			printf("ErrCode = %02x\n", (u16)err);
		#endif
			return;
		}
		make_packet(COM_PKT_CMD_ISO15693_GET_SYSTEM, resbuff, bufflen);
		
	}	
}
void com_get_block_status(u8 *pcmd)
{
	u8 i;
	u8 err = 0;
	u8 block_status[12];
	u16 block_status_length;
	int status = MI_OK;
	
	status = pcd_get_multiple_block_security_status(iso15693_uid, pcmd[1], pcmd[2], pcmd[3], &err, block_status, &block_status_length);
	
	if(status == MI_OK)
	{
		if(err != 0)
		{
		#if(NFC_DEBUG)
			printf("ErrCode = %02x\n", (u16)err);
		#endif
			return;
		}
#if(NFC_DEBUG)
		printf("block_status: ");
		for(i = 0; i < block_status_length; i++)
		{
			printf(" %02x", block_status[block_status_length]);
		}
		printf("\n");
#endif
	}
}

void com_read_single_block(u8 *pcmd)
{
	u8 err = 0;
	u8 block_data[5];
	u16 data_length;
	int status = MI_OK;
	
	status = pcd_read_single_block(iso15693_uid, pcmd[1], pcmd[2], block_data, &err, &data_length);

	if(status == MI_OK)
	{
		if(err != 0)
		{
            #if(NFC_DEBUG)
			printf("ErrCode = %02x\n", (u16)err);
            #endif
			return;
		}
		if(pcmd[1] & BIT6)
		{
//			make_packet(COM_PKT_CMD_ISO15693_READ_SINGLE, &block_data[1], data_length - 1);
		}
		else
		{
//			make_packet(COM_PKT_CMD_ISO15693_READ_SINGLE, block_data, data_length);
		}
	}

}

void com_write_single_block(u8 *pcmd)
{
	u8 err = 0;
	u16 data_length = 4;
	int status = MI_OK;
	u8 recvbuff[2];
	u16 recvlen;
	
	status = pcd_write_single_block(iso15693_uid, pcmd[1], pcmd[2], &pcmd[3], &err, data_length);
	
	if(status == MI_OK)
	{
		if(err != 0)
		{
#if(NFC_DEBUG)
			printf("ErrCode = %02x\n", (u16)err);
#endif
			return;
		}
	}
	else if((pcmd[1] & OPTION_FLAG) && (status == MI_NOTAGERR))
	{
		status = pcd_send_eof(recvbuff, &recvlen);
	}
}

void com_lock_block(u8 *pcmd)
{
	u8 err = 0;
	int status = MI_OK;
	
	status = pcd_lock_block(iso15693_uid, pcmd[1], pcmd[2], &err);

	if(status == MI_OK)
	{
		if(err != 0)
		{
		#if(NFC_DEBUG)
			printf("ErrCode = %02x\n", (u16)err);
		#endif
			return;
		}
	}
}

void com_read_multiple_block(u8 *pcmd)

{
	u8 err = 0;
	u8 XDATA databuff[40];
	u16 datalen;
	int status = MI_OK;	

	status = pcd_read_multiple_block(iso15693_uid, pcmd[1], pcmd[2], pcmd[3], databuff, &err, &datalen);

	if(status == MI_OK)
	{
		if(err != 0)
		{
		#if(NFC_DEBUG)
			printf("ErrCode = %02x\n", (u16)err);
		#endif
			return;
		}
	}	
}

void com_write_multiple_block(u8 *pcmd)
{
	u8 err = 0;
	u8 XDATA databuff[40] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C};
	u16 datalen = 12;
	int status = MI_OK;	

	status = pcd_write_multiple_block(iso15693_uid, pcmd[1], pcmd[2], pcmd[3], databuff, &err, datalen);

	if(status == MI_OK)
	{
		if(err != 0)
		{
		#if(NFC_DEBUG)
			printf("ErrCode = %02x\n", (u16)err);
		#endif
			return;
		}
	}	
}

void com_write_afi(u8 * pcmd)
{
	u8 err = 0;
	int status = MI_OK;	

	status = pcd_write_afi(iso15693_uid, pcmd[1], pcmd[2], &err);

	if(status == MI_OK)
	{
		if(err != 0)
		{
		#if(NFC_DEBUG)
			printf("ErrCode = %02x\n", (u16)err);
		#endif
			return;
		}
	}	
}

void com_lock_afi(u8 *pcmd)
{
	u8 err = 0;
	int status = MI_OK;	

	status = pcd_lock_afi(iso15693_uid, pcmd[1], &err);

	if(status == MI_OK)
	{
		if(err != 0)
		{
		#if(NFC_DEBUG)
			printf("ErrCode = %02x\n", (u16)err);
		#endif
			return;
		}
	}	
}

void com_write_dsfid(u8 * pcmd)
{
	u8 err = 0;
	int status = MI_OK;	

	status = pcd_write_dsfid(iso15693_uid, pcmd[1], pcmd[2], &err);

	if(status == MI_OK)
	{
		if(err != 0)
		{
		#if(NFC_DEBUG)
			printf("ErrCode = %02x\n", (u16)err);
		#endif
			return;
		}
	}	
}

void com_lock_dsfid(u8 *pcmd)
{
	u8 err = 0;
	int status = MI_OK;	

	status = pcd_lock_dsfid(iso15693_uid, pcmd[1], &err);

	if(status == MI_OK)
	{
		if(err != 0)
		{
		#if(NFC_DEBUG)
			printf("ErrCode = %02x\n", (u16)err);
		#endif
			return;
		}
	}	
}
